#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time   : 2023-11-26 15:09
# @Author : hard work
# @File    : renix_RFC2544.py
# @Description :
from common.renix_basic_config.renix_config import renix_config
from traffic_tool.tool_renix.renix_empty.renix_basic_empty import Renix_basic_config
from renix_py_api.api_gen import *

from renix_py_api.renix import *

from renix_py_api.benchmark_test.benchmark_test_api import *


class Renix_RFC2544(Renix_basic_config):
    def __init__(self, **kwargs):
        super().__init__()
        if renix_config():
            """使用配置文件(../common/renix_basic_config/renix_config.py)中的配置"""
            Renix_basic_config.chassis_address = renix_config()['chassis_address']
            Renix_basic_config.slot = renix_config()['slot']
            Renix_basic_config.port1 = renix_config()['port1']
            Renix_basic_config.port2 = renix_config()['port2']
            Renix_basic_config.port3 = renix_config()['port3']
            Renix_basic_config.port4 = renix_config()['port4']
            Renix_basic_config.port5 = renix_config()['port5']
            Renix_basic_config.renix_install_addr = renix_config()['renix_install_addr']
        else:
            """使用自定义配置"""
            if not kwargs:
                return
            # 如果不使用默认配置，此处修改你自己的配置
            Renix_basic_config.chassis_address = kwargs['chassis_address']
            Renix_basic_config.slot = kwargs['slot']
            Renix_basic_config.port1 = kwargs['port1']
            Renix_basic_config.port2 = kwargs['port2']
            Renix_basic_config.port3 = kwargs['port3']
            Renix_basic_config.port4 = kwargs['port4']
            Renix_basic_config.port5 = kwargs['port5']
            Renix_basic_config.renix_install_addr = kwargs['renix_install_addr']
        Renix_basic_config().set_renix_SysVariable()
        self.chassis = None
        self.Port_1 = None
        self.Port_2 = None
        self.Port_3 = None
        self.Port_4 = None
        self.sys_entry = None

    def set_renix_rfc2544_start(self, save_result_file):
        initialize()
        self.sys_entry = get_sys_entry()
        self.Port_1 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port1))
        self.Port_2 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port2))
        self.Port_3 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port3))
        self.Port_4 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port4))

        bring_port_online_cmd = BringPortsOnlineCommand(
            PortList=[self.Port_1.handle, self.Port_2.handle, self.Port_3.handle, self.Port_4.handle])

        bring_port_online_cmd.execute()

        interface1 = Interface(upper=self.Port_1)

        interface2 = Interface(upper=self.Port_2)

        interface3 = Interface(upper=self.Port_3)

        interface4 = Interface(upper=self.Port_4)

        build_ipv4_interface = BuildInterfaceCommand(
            InterfaceList=[interface1.handle, interface2.handle, interface3.handle, interface4.handle],
            NetworkLayers=['eth'])

        build_ipv4_interface.execute()

        eth_layer1 = interface1.get_children('EthIILayer')[0]

        eth_layer1.edit(Address='00:00:02:01:01:02')

        eth_layer2 = interface2.get_children('EthIILayer')[0]

        eth_layer2.edit(Address='00:00:02:01:01:03')

        eth_layer3 = interface3.get_children('EthIILayer')[0]

        eth_layer3.edit(Address='00:00:02:01:01:04')

        eth_layer4 = interface4.get_children('EthIILayer')[0]

        eth_layer4.edit(Address='00:00:02:01:01:05')

        clear_smart_scripter_commands()

        wizard_config, (addr_cach_config, addr_rate_config) = get_benchmark_wizard_config(benchmark_test='rfc2889',
                                                                                          test_items=(
                                                                                              'addressCachingCapacity',
                                                                                              'addressLearningRate'))

        relate_ports(wizard_config, [self.Port_1, self.Port_2, self.Port_3, self.Port_4])

        create_streams(wizard_config, ('addressCachingCapacity', 'addressLearningRate'), 'eth',
                       [eth_layer1, eth_layer2], [eth_layer3, eth_layer4], bidirectional=False, mesh_mode='1v1')

        config_result_file_name(addr_cach_config, use_custom_result_file_name=True,
                                result_file_name='test_2889_addr_cach', append_timestamp=True)

        config_address_learning([addr_cach_config, addr_rate_config], learning_frequency='once',
                                enable_address_learning=False)

        config_latency_parameters([addr_cach_config, addr_rate_config], latency_type='FIFO',
                                  delay_before_start_stream=2, delay_after_stop_stream=2)

        # save result file
        config_result_path([addr_cach_config, addr_rate_config], abs_path=save_result_file)

        config_test_duration(addr_cach_config, trial_number=1)

        config_frame_size_loop(addr_cach_config, loop_type='custom', start_length=80, end_length=80, step_length=10,
                               custom_length=(64,))

        config_address_learning_capacity(addr_cach_config, min_address_count=1, max_address_count=65536,
                                         init_address_count=65535, resolution=2, aging_time=15, learning_rate=10000)

        config_result_file_name(addr_rate_config, use_custom_result_file_name=True,
                                result_file_name='test_2889_addr_rate', append_timestamp=True)

        config_test_duration(addr_rate_config, trial_number=1)

        config_frame_size_loop(addr_rate_config, loop_type='custom', start_length=80, end_length=80, step_length=10,
                               custom_length=(64,))

        config_address_learning_rate(addr_rate_config, min_rate_count=1, max_rate_count=14880, init_rate_count=14880,
                                     resolution=2, aging_time=15, address_count=1000)

        command = ExpandWizardCommand(WizardConfig=wizard_config.handle)

        command.execute()

        start_cmd = StartSmartScripterCommand()

        start_cmd.execute()

        get_state = sys_entry.get_children('SmartScripter')[0]

        get_state.get()

        stop_cmd = StopSmartScripterCommand()

        stop_cmd.execute()

        # Configuration of RFC2889 forwarding tests
        clear_smart_scripter_commands()

        wizard_config, (broadcast_forward_config, broadcast_latency_config) = get_benchmark_wizard_config(
            benchmark_test='rfc2889', test_items=('broadcastForwarding', 'broadcastLatency'))

        relate_ports(wizard_config, [self.Port_1, self.Port_2, self.Port_3, self.Port_4])

        create_streams(wizard_config, ('broadcastForwarding', 'broadcastLatency'), 'eth', [eth_layer1],
                       [eth_layer2, eth_layer3, eth_layer4], bidirectional=False, mesh_mode='1v1')

        config_result_file_name(broadcast_forward_config, use_custom_result_file_name=True,
                                result_file_name='test_2889_broadcast_forward', append_timestamp=True)

        config_address_learning([broadcast_forward_config, broadcast_latency_config], learning_frequency='once',
                                enable_address_learning=False)

        config_latency_parameters([broadcast_forward_config, broadcast_latency_config], latency_type='FIFO',
                                  delay_before_start_stream=2, delay_after_stop_stream=2)
        # save result file
        config_result_path([broadcast_forward_config, broadcast_latency_config], abs_path=save_result_file)

        config_test_duration(broadcast_forward_config, trial_number=1, duration_mode='second', duration_count=10)

        config_frame_size_loop(broadcast_forward_config, loop_type='step', start_length=80, end_length=80,
                               step_length=10)

        config_binary_search_parameters(broadcast_forward_config, search_mode='binary', lower_rate=1, upper_rate=100,
                                        init_rate=100, step_rate=10, resolution=1, back_off_ratio=50, acceptance_loss=0)

        config_result_file_name(broadcast_latency_config, use_custom_result_file_name=True,
                                result_file_name='test_2889_broadcast_latency', append_timestamp=True)

        config_test_duration(broadcast_latency_config, trial_number=1)

        config_frame_size_loop(broadcast_latency_config, loop_type='step', start_length=80, end_length=80,
                               step_length=10)

        command = ExpandWizardCommand(WizardConfig=wizard_config.handle)

        command.execute()

        start_cmd = StartSmartScripterCommand()

        start_cmd.execute()

        get_state = sys_entry.get_children('SmartScripter')[0]

        get_state.get()

        stop_cmd = StopSmartScripterCommand()

        stop_cmd.execute()

        clear_smart_scripter_commands()

        wizard_config, (congestion_config,) = get_benchmark_wizard_config(benchmark_test='rfc2889',
                                                                          test_items=('congestionControl',))

        relate_ports(wizard_config, [self.Port_1, self.Port_1, self.Port_1, self.Port_1])

        create_streams(wizard_config, ('congestionControl',), 'eth', [eth_layer1, eth_layer2], [eth_layer3, eth_layer4],
                       bidirectional=False, mesh_mode='congestion')

        config_result_file_name(congestion_config, use_custom_result_file_name=True,
                                result_file_name='test_2889_congestion', append_timestamp=True)

        config_address_learning([congestion_config], learning_frequency='once', enable_address_learning=True)

        config_latency_parameters([congestion_config], latency_type='FIFO', delay_before_start_stream=2,
                                  delay_after_stop_stream=10)
        # save result file
        config_result_path([congestion_config], abs_path=save_result_file)

        config_test_duration(congestion_config, trial_number=1, duration_mode='second', duration_count=10)

        config_frame_size_loop(congestion_config, loop_type='step', start_length=80, end_length=80, step_length=10)

        config_traffic_load_loop(congestion_config, load_unit='percent', load_mode='custom', load_custom=(60,))

        expand_cmd = ExpandWizardCommand(WizardConfig=wizard_config.handle)

        expand_cmd.execute()

        start_cmd = StartSmartScripterCommand()

        start_cmd.execute()

        get_state = sys_entry.get_children('SmartScripter')[0]

        get_state.get()

        stop_cmd = StopSmartScripterCommand()

        stop_cmd.execute()

        clear_smart_scripter_commands()

        wizard_config, (errored_frame_config,) = get_benchmark_wizard_config(benchmark_test='rfc2889',
                                                                             test_items=('erroredFrameFilter',))

        relate_ports(wizard_config, [self.Port_1, self.Port_2, self.Port_3, self.Port_4])

        create_streams(wizard_config, ('erroredFrameFilter',), 'eth', [eth_layer1, eth_layer2],
                       [eth_layer3, eth_layer4], bidirectional=True, mesh_mode='1v1')

        config_result_file_name(errored_frame_config, use_custom_result_file_name=True,
                                result_file_name='test_2889_errored_frame', append_timestamp=True)

        config_address_learning([errored_frame_config], learning_frequency='once', enable_address_learning=True)

        config_latency_parameters([errored_frame_config], latency_type='FIFO', delay_before_start_stream=2,
                                  delay_after_stop_stream=10)

        # save result file
        config_result_path([errored_frame_config], abs_path=save_result_file)

        config_test_duration(errored_frame_config, trial_number=1, duration_mode='second', duration_count=5)

        config_traffic_load_loop(errored_frame_config, load_unit='percent', load_mode='custom', load_custom=(60,))

        config_errored_frame_filtering(errored_frame_config, crc_tested=True, crc_frame_length=64,
                                       undersized_tested=True, undersized_frame_length=60, oversized_tested=True,
                                       oversized_frame_length=1519, max_legal_frame_length=1518)

        command = ExpandWizardCommand(WizardConfig=wizard_config.handle)

        command.execute()

        start_cmd = StartSmartScripterCommand()

        start_cmd.execute()

        get_state = sys_entry.get_children('SmartScripter')[0]

        get_state.get()

        stop_cmd = StopSmartScripterCommand()

        stop_cmd.execute()

        clear_smart_scripter_commands()

        wizard_config, (forwarding_config,) = get_benchmark_wizard_config(benchmark_test='rfc2889',
                                                                          test_items=('forwarding',))

        relate_ports(wizard_config, [self.Port_1, self.Port_2, self.Port_3, self.Port_4])

        create_streams(wizard_config, ('forwarding',), 'eth', [eth_layer1, eth_layer2], [eth_layer3, eth_layer4],
                       bidirectional=True, mesh_mode='meshed')

        config_result_file_name(forwarding_config, use_custom_result_file_name=True,
                                result_file_name='test_2889_forwarding', append_timestamp=True)

        config_address_learning([forwarding_config], learning_frequency='once', enable_address_learning=True)

        config_latency_parameters([forwarding_config], latency_type='FIFO', delay_before_start_stream=2,
                                  delay_after_stop_stream=10)

        # save result file
        config_result_path([forwarding_config], abs_path=save_result_file)

        config_test_duration(forwarding_config, trial_number=1, duration_mode='second', duration_count=10)

        config_frame_size_loop(forwarding_config, loop_type='step', start_length=80, end_length=80, step_length=10)

        config_binary_search_parameters(forwarding_config, search_mode='binary', lower_rate=1, upper_rate=100,
                                        init_rate=100, step_rate=10, resolution=1, back_off_ratio=50, acceptance_loss=0)

        command = ExpandWizardCommand(WizardConfig=wizard_config.handle)

        command.execute()

        start_cmd = StartSmartScripterCommand()

        start_cmd.execute()

        get_state = sys_entry.get_children('SmartScripter')[0]

        get_state.get()

        stop_cmd = StopSmartScripterCommand()

        stop_cmd.execute()
